#ifndef SCREEN_H
#define SCREEN_H

#include <TFT_eSPI.h>
#include <Arduino.h>
#include <TJpg_Decoder.h>
#include "../globals.h"
#include "../logger.h"
#include "../assets/logo_jpg.h"

static const uint16_t screenWidth  = 320;
static const uint16_t screenHeight = 240;

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

inline void set_brightness(int _brightness, bool remenber=true){
   if (_brightness < 255 && _brightness > 5){
      analogWrite(PIN_BLK, _brightness);
      if (remenber) {brightness = _brightness;}
   }else if(_brightness >= 255) 
    {
        digitalWrite(PIN_BLK, HIGH);
        if (remenber){brightness = _brightness;}
   }else if(_brightness <= 5)
   {
    analogWrite(PIN_BLK, 5); 
    if(remenber){brightness = _brightness;}
   }
}

// 平滑的亮起
void smooth_on(){
   digitalWrite(PIN_BLK, LOW);
   for(int i=0; i<brightness; i++){
      set_brightness(i, false);
      delay(2);
   }
}

void smooth_off(){
   analogWrite(PIN_BLK, brightness);
   for(int i=brightness; i>=0; i--){
      analogWrite(PIN_BLK, i);
      delay(2);
   }
}

uint16_t* logoBuffer1 = nullptr; // Toggle buffer for 16*16 MCU block
uint16_t* logoBuffer2 = nullptr; // Toggle buffer for 16*16 MCU block
uint16_t* logoBufferPtr = logoBuffer1;
bool logoBufferSel = 0;
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap){
   // Stop further decoding as image is running off bottom of screen
  if ( y >= tft.height() ) return 0;
  if (logoBufferSel) logoBufferPtr = logoBuffer2;
  else logoBufferPtr = logoBuffer1;
  logoBufferSel = !logoBufferSel; // Toggle buffer selection
  //  pushImageDMA() will clip the image block at screen boundaries before initiating DMA
  tft.pushImageDMA(x, y, w, h, bitmap, logoBufferPtr); // Initiate DMA - blocking only if last DMA is not complete
  // The DMA transfer of image block to the TFT is now in progress...
  // Return 1 to decode next block.
  return 1;
}


void render_logo(){
   tft.fillScreen(TFT_BLACK);
   TJpgDec.setJpgScale(1);
   // TJpgDec callback 已在 screen_init 中设置
   uint16_t w = 0, h = 0;
   TJpgDec.getJpgSize(&w, &h, logo, sizeof(logo));
   tft.startWrite();
   TJpgDec.drawJpg(0, 0, logo, sizeof(logo));
   tft.endWrite();
}

void screen_element_prepare(){ 
    tft.fillScreen(TFT_BLACK);
}

void screen_init(){
    logln("Initializing screen...");
    pinMode(PIN_BLK, OUTPUT);
    // pinMode(PIN_SCREEN_VDD, OUTPUT);
    digitalWrite(PIN_BLK, LOW);
    // digitalWrite(PIN_SCREEN_VDD, LOW);
    // delay(1000);
    tft.init();
    tft.setRotation(1); /* Landscape orientation, flipped */
    tft.setSwapBytes(true);
    tft.initDMA();
    tft.invertDisplay(false);//翻转颜色
    logln("Screen powerd on.");

    // 为 TJpg_Decoder 分配持续使用的双缓冲（用于 pushImageDMA）
    if (logoBuffer1 == nullptr) {
        logoBuffer1 = (uint16_t*)malloc(16 * 16 * sizeof(uint16_t));
    }
    if (logoBuffer2 == nullptr) {
        logoBuffer2 = (uint16_t*)malloc(16 * 16 * sizeof(uint16_t));
    }
    if (logoBuffer1 == nullptr || logoBuffer2 == nullptr) {
        logln("Failed to allocate logo buffers!");
        if (logoBuffer1){ free(logoBuffer1); logoBuffer1=nullptr;}
        if (logoBuffer2){ free(logoBuffer2); logoBuffer2=nullptr;}
        // 继续但后续解码可能失败
    }

    // 将 TJpg 解码回调设置为 pushImageDMA 回调
    TJpgDec.setCallback(tft_output);

    render_logo();
    delay(300);
    smooth_on();
    logf("Logo rendered %d\n", brightness);
    delay(500);
    smooth_off();
    screen_element_prepare();
    smooth_on();
}

// 新增：用于绘制 JPEG 数据（来自相机）
void screen_draw_jpeg(const uint8_t* jpg_data, size_t len){
    if (jpg_data == nullptr || len == 0) return;
    // 保证回调已设置
    TJpgDec.setJpgScale(1);
    TJpgDec.setCallback(tft_output);
    tft.startWrite();
    TJpgDec.drawJpg(0, 0, jpg_data, len);
    tft.endWrite();
}

// 新增函数：裁剪并显示 JPEG 数据
void screen_draw_cropped_jpeg(const uint8_t* jpg_data, size_t len) {
    if (jpg_data == nullptr || len == 0) return;
    
    // 设置解码参数
    TJpgDec.setJpgScale(1);
    TJpgDec.setCallback(tft_output);
    
    // 获取 JPEG 图像尺寸（可用于后续优化/检查）
    uint16_t imgWidth, imgHeight;
    TJpgDec.getJpgSize(&imgWidth, &imgHeight, jpg_data, len);
    
    // 计算裁剪参数（从第32像素开始，显示256像素宽度）
    int cropX = 32;  // 左边裁剪32像素

    tft.startWrite();
    // 使用库提供的 drawJpg(x, y, array, size) 重载，
    // 传入负的 x 值以在显示时实现水平裁剪/偏移，
    // TJpgDec 回调与 TFT 的 pushImageDMA 会在边界处裁剪块。
    TJpgDec.drawJpg(-cropX, 0, jpg_data, len);
    tft.endWrite();
}
void screen_update(){
    // 旧的测试循环可保留备用，但用于实时显示时可不使用
    delay(1000);
    tft.fillScreen(TFT_BLUE);
    delay(1000);
    tft.fillScreen(TFT_RED);
    delay(1000);
    tft.fillScreen(TFT_YELLOW);
    logln("Screen looped.");
}

#endif // SCREEN_H